home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / QuickDraw3D 1.6 SDK / Mac SampleCode Previous / Geometry Samples- Mac / GeometryTest / GTFile.c < prev    next >
Encoding:
Text File  |  1999-05-18  |  9.1 KB  |  372 lines  |  [TEXT/MPCC]

  1. // GTFile.c, file and metafile routines
  2.  
  3.  
  4. // system headers
  5. #include <Devices.h>
  6. #include <Dialogs.h>
  7. #include <DiskInit.h>
  8. #include <Fonts.h>
  9. #include <Menus.h>
  10. #include <PictUtils.h>
  11. #include <QDOffScreen.h>
  12. #include <QuickDraw.h>
  13. #include <Resources.h>
  14. #include <SegLoad.h>
  15. #include <StandardFile.h>
  16. #include <TextEdit.h>
  17. #include <ToolUtils.h>
  18.  
  19. #include "GTSupport.h"
  20. #include "GTFile.h"
  21.  
  22. #include "QD3D.h"
  23. #include "QD3DDrawContext.h"
  24. #include "QD3DRenderer.h"
  25. #include "QD3DShader.h"
  26. #include "QD3DCamera.h"
  27. #include "QD3DLight.h"
  28. #include "QD3DGeometry.h"
  29. #include "QD3DTransform.h"
  30. #include "QD3DGroup.h"
  31. #include "QD3DMath.h"
  32.  
  33. #include "QD3DStorage.h"
  34. #include "QD3DIO.h"
  35.  
  36.  
  37. //-------------------------------------------------------------------------------------------
  38. //
  39.  
  40. static void InitDocumentData( DocumentHdl theDocument ) 
  41. {
  42.     TQ3Point3D        myOrigin = { 0, 0, 0 } ;
  43.     
  44.     // sanity check
  45.     if( theDocument == nil || (**theDocument).fWindow == nil )
  46.         return ;
  47.         
  48.     // Lock and load
  49.     HLock( (Handle)theDocument ) ;
  50.     
  51.     // sets up the 3d data for the scene
  52.     //    Create view for QuickDraw 3D.
  53.     (**theDocument).fView = MyNewView( (**theDocument).fWindow );
  54.  
  55.     // the main display group:
  56.     (**theDocument).fModel = NULL ;    
  57.     
  58.     // the drawing styles:
  59.     (**theDocument).fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  60.     (**theDocument).fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
  61.     (**theDocument).fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  62.  
  63.  
  64.     (**theDocument).fGroupScale = 1;                
  65.     (**theDocument).fGroupCenter = myOrigin ;    
  66.     
  67.     // set up an illumination shder for this document
  68.     (**theDocument).fShader = Q3PhongIllumination_New();        
  69.  
  70.     // set the rotation matrix the identity matrix
  71.     Q3Matrix4x4_SetIdentity(&(**theDocument).fRotation);    
  72.                     
  73.     // unlock the handle            
  74.     HUnlock((Handle) theDocument ) ;
  75.     
  76.     return ;
  77.     
  78. bail:
  79.     // either we failed getting the model or the view
  80.     // so we want to quit here
  81.     ExitToShell() ;
  82.     
  83. }
  84.  
  85. //-------------------------------------------------------------------------------------------
  86. //
  87.  
  88. static void DisposeDocumentData( DocumentHdl theDocument )
  89. {
  90.     // Lock and load
  91.     HLock( (Handle)theDocument ) ;
  92.     
  93.     if( (**theDocument).fView ) 
  94.         Q3Object_Dispose((**theDocument).fView) ;                // the view for the scene
  95.  
  96.     if( (**theDocument).fModel )  
  97.         Q3Object_Dispose((**theDocument).fModel) ;                // object in the scene being modelled
  98.  
  99.     if( (**theDocument).fInterpolation )  
  100.         Q3Object_Dispose((**theDocument).fInterpolation) ;        // interpolation style used when rendering
  101.  
  102.     if( (**theDocument).fBackFacing )  
  103.         Q3Object_Dispose((**theDocument).fBackFacing) ;            // whether to draw shapes that face away from the camera
  104.  
  105.     if( (**theDocument).fFillStyle )  
  106.         Q3Object_Dispose((**theDocument).fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  107.  
  108.     if( (**theDocument).fShader )  
  109.         Q3Object_Dispose((**theDocument).fShader) ;
  110.  
  111.     HUnlock((Handle) theDocument ) ;
  112.     
  113.     // And free the storage used by the document handle
  114.     DisposHandle((Handle) theDocument);
  115. }
  116.  
  117. //-------------------------------------------------------------------------------------------
  118. //
  119. void HandleCloseWindow( WindowPtr theWindow )
  120. {
  121.     DocumentHdl     theDocument ;
  122.     
  123.     if( theWindow ) {
  124.         theDocument = (DocumentHdl) GetWRefCon( theWindow ) ;
  125.         DisposeWindow ( theWindow );
  126.         if( theDocument )
  127.             DisposeDocumentData( theDocument ) ;
  128.     }
  129.  
  130. }
  131.  
  132.  
  133. //-------------------------------------------------------------------------------------------
  134. // Create and init a document with the 3d stuff - gets called by both open and new
  135.  
  136. static DocumentHdl    CreateDocument( void ) 
  137. {
  138.     DocumentHdl        theDocument;
  139.     WindowPtr        theWindow = nil ;
  140.     OSErr            theErr = noErr ;
  141.     
  142.     if(( theDocument = (DocumentHdl)NewHandleClear( sizeof(DocumentRec))) != nil )
  143.     {
  144.         theWindow = GetNewCWindow(128,nil,(WindowPtr)-1);
  145.         if( theWindow == nil ) 
  146.             return nil ;
  147.         
  148.         SetWRefCon( theWindow, (long)theDocument );
  149.         (**theDocument).fWindow = theWindow ;
  150.         
  151.         // initialise our document structure
  152.         InitDocumentData( theDocument ) ;
  153.     
  154.     }
  155.     else // handle the error
  156.         theErr = MemError() ;
  157.     
  158.     return theDocument ;        
  159. }
  160.  
  161. OSErr    HandleNewCommand( void )
  162. {
  163.     DocumentHdl    theDocument ;
  164.     OSErr        theErr = noErr ;
  165.     theDocument = CreateDocument() ;
  166.     if(theDocument == nil )
  167.     {
  168.         theErr = MemError() ;
  169.         if( theErr == noErr )
  170.         {
  171.             theErr = ResError() ;
  172.         }
  173.     
  174.     }
  175.     return theErr ;
  176. }
  177.  
  178. //-------------------------------------------------------------------------------------------
  179. //
  180. static Boolean MetafileFileSpecify( FSSpec *theFile )
  181. {
  182.     StandardFileReply    theSFReply ;
  183.     SFTypeList            myTypes = { 'TEXT', '3DMF' } ;
  184.     const short            numTypes = 2 ;
  185.         
  186.     // Get the file name to open
  187.     StandardGetFile( nil, numTypes, myTypes, &theSFReply ) ;
  188.     
  189.     if( theSFReply.sfGood )
  190.         *theFile = theSFReply.sfFile ;
  191.     
  192.     // did the user cancel?
  193.     return theSFReply.sfGood ;
  194.     
  195. }
  196.  
  197. //-----------------------------------------------------------------------------------------------
  198. //
  199. OSErr    HandleOpenCommand( void )
  200. {
  201.     DocumentHdl    theDocument ;
  202.     OSErr        theErr = noErr ;
  203.     FSSpec        theFileSpec ;
  204.     
  205.     
  206.     theDocument = CreateDocument() ;
  207.     if(theDocument == nil )
  208.     {
  209.         theErr = MemError() ;
  210.         if( theErr == noErr )
  211.         {
  212.             theErr = ResError() ;
  213.         }
  214.         return theErr ;
  215.     }
  216.  
  217.     if(MetafileFileSpecify( &theFileSpec )) {
  218.     
  219.         WindowPtr        myWindow = (**theDocument).fWindow ;
  220.     
  221.         SetCursor(*(GetCursor(watchCursor)));
  222.         HLock((Handle)theDocument) ;
  223.         
  224.         // try to read the file into the main display group
  225.         if(((**theDocument).fModel = MyNewModelFromFile(&theFileSpec)) != NULL ) {        
  226.  
  227.             AdjustCamera(    theDocument,
  228.                             (myWindow->portRect.right - myWindow->portRect.left),
  229.                             (myWindow->portRect.bottom - myWindow->portRect.top) ) ;
  230.  
  231.             SetWTitle( myWindow, theFileSpec.name );
  232.             ShowWindow( myWindow ) ;
  233.             SetPort( myWindow ) ;
  234.     
  235.             SetCursor(&qd.arrow) ;
  236.             
  237.         }
  238.         
  239.         HUnlock((Handle)theDocument) ;
  240.     }
  241.  
  242.     return theErr ;
  243. }    
  244.  
  245.  
  246. //-----------------------------------------------------------------------------------------------
  247. // cleaned up from IM QuickDraw 3D pp 15-5
  248. static TQ3FileObject MyGetNewFile( FSSpec *myFSSpec, TQ3Boolean *isText )
  249. {
  250.     TQ3FileObject        myFileObj;
  251.     TQ3StorageObject        myStorageObj;
  252.     OSType                myFileType;
  253.     
  254.     FInfo                fndrInfo ;
  255.  
  256.     // we assume the FSSpec passed in was valid, get the file information
  257.     // we need to know the file type, this routine may get called by an appleEvent
  258.     // handler, so we can't assume a type, we need to get it from the fsspec.
  259.     
  260.     FSpGetFInfo( myFSSpec, &fndrInfo ) ;
  261.     
  262.     // pull out the file type
  263.     
  264.     myFileType = fndrInfo.fdType ;
  265.     
  266.     // Create new storage object and new file object 
  267.     if(((myStorageObj = Q3FSSpecStorage_New( myFSSpec )) == NULL) 
  268.         || ((myFileObj = Q3File_New()) == NULL)) 
  269.     {
  270.         if (myStorageObj != NULL) 
  271.             Q3Object_Dispose(myStorageObj);
  272.         return(NULL);
  273.     }
  274.  
  275.     // Set the storage for the file object
  276.     Q3File_SetStorage(myFileObj, myStorageObj);
  277.     Q3Object_Dispose(myStorageObj);
  278.  
  279.     if ((myFileType == '3DMF') || (myFileType == 'EO3D'))
  280.         *isText = kQ3False ;
  281.     else if (myFileType == 'TEXT')
  282.         *isText = kQ3True ;
  283.  
  284.     return (myFileObj);
  285. }
  286.  
  287.  
  288. //----------------------------------------------------------------------------------
  289. // read model from file object into the supplied group
  290.  
  291. static TQ3Status MyReadModelFromFile( TQ3FileObject theFile,TQ3GroupObject myGroup)
  292. {    
  293.     if(theFile != NULL) {
  294.     
  295.         TQ3Object            myTempObj ;
  296.         TQ3Boolean            isEOF ;
  297.                 
  298.     
  299.         // read objects from the file
  300.         do {
  301.         
  302.             myTempObj = Q3File_ReadObject( theFile );
  303.             
  304.             if( myTempObj != NULL ) {
  305.                 // we only want the object in our main group if we can draw it
  306.                 if ( Q3Object_IsDrawable( myTempObj) ) 
  307.                     Q3Group_AddObject( myGroup, myTempObj ) ;
  308.                 
  309.                 // we either added the object to the main group, or we don't care
  310.                 // so we can safely dispose of the object
  311.                 Q3Object_Dispose( myTempObj ) ;
  312.             }
  313.             
  314.             // check to see if we reached the end of file yet
  315.             isEOF = Q3File_IsEndOfFile( theFile );
  316.             
  317.         } while (isEOF == kQ3False);    
  318.     }
  319.     
  320.     if( myGroup != NULL )
  321.         return kQ3Success ;
  322.     else
  323.         return kQ3Failure ;
  324. }
  325.  
  326. //----------------------------------------------------------------------------------
  327. // attach a shader to the group
  328.  
  329. static TQ3Status MyAddShaderToGroup( TQ3GroupObject group )
  330. {
  331.     TQ3ShaderObject    illuminationShader = Q3PhongIllumination_New();
  332.  
  333.     Q3Group_AddObject(group, illuminationShader);
  334.     Q3Object_Dispose(illuminationShader);
  335.     return(kQ3Success);
  336. }
  337.  
  338. //----------------------------------------------------------------------------------
  339.  
  340. static TQ3GroupObject MyNewModelFromFile(FSSpec *theFileSpec)
  341. {
  342.     TQ3GroupObject        myGroup = NULL ;
  343.     TQ3Boolean            isText = kQ3False ;
  344.     TQ3FileMode            myFileMode = 0;
  345.     TQ3FileObject        theFile;
  346.     
  347.     //    Create a ordered group for the complete model.
  348.     if ((myGroup = Q3DisplayGroup_New()) == NULL )
  349.         return NULL;
  350.         
  351.     MyAddShaderToGroup( myGroup ) ;
  352.  
  353.     theFile = MyGetNewFile( theFileSpec, &isText ) ;
  354.     
  355.     if( isText == kQ3True )
  356.         myFileMode |= kQ3FileModeText;    // is it a text metafile??    
  357.  
  358.     // Open the file object
  359.     if( Q3File_OpenRead( theFile, &myFileMode ) != kQ3Success)
  360.         return  NULL ;
  361.  
  362.     if( MyReadModelFromFile( theFile, myGroup ) == NULL)
  363.         DebugStr("\pMetafile data read is null") ;
  364.     
  365.     Q3File_Close(theFile);            // close and dispose of the file object
  366.     Q3Object_Dispose(theFile);
  367.     
  368.     return myGroup ;
  369. }
  370.  
  371.  
  372.